package com.shishi.fast.generator.service.impl;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shishi.fast.common.exception.ApiException;
import com.shishi.fast.common.util.DateTimeUtils;
import com.shishi.fast.common.vo.ResultCode;
import com.shishi.fast.generator.domain.DeviceDO;
import com.shishi.fast.generator.domain.DeviceRepairDO;
import com.shishi.fast.generator.domain.DeviceTemplateDO;
import com.shishi.fast.generator.excel.DeviceRepairImportExcel;
import com.shishi.fast.generator.mapper.DeviceMapper;
import com.shishi.fast.generator.mapper.DeviceRepairMapper;
import com.shishi.fast.generator.mapper.DeviceTemplateMapper;
import com.shishi.fast.generator.service.DeviceRepairService;
import com.shishi.fast.generator.vo.DeviceRepairRequest;
import com.shishi.fast.generator.vo.TemplateResponse;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.*;

/**
 *
 */
@Transactional(rollbackFor = Exception.class)
@Service
public class DeviceRepairServiceImpl extends ServiceImpl<DeviceRepairMapper, DeviceRepairDO> implements DeviceRepairService {

    @Autowired
    private DeviceMapper deviceMapper;

    @Autowired
    private DeviceRepairMapper deviceRepairMapper;

    @Autowired
    private DeviceTemplateMapper deviceTemplateMapper;

    @Override
    public void generateData(DeviceRepairRequest.GenerateDataParam param) {
        List<DeviceDO> deviceDOList = deviceMapper.selectList(Wrappers.<DeviceDO>lambdaQuery()
                .eq(DeviceDO::getCompanyId, param.getCompanyId())
                .eq(DeviceDO::getDeleted, 0)
        );

        for (DeviceDO deviceDO : deviceDOList) {
            List<DeviceRepairDO> list = generateRepairData(param.getStartDate(), param.getEndDate(), param.getRepairCount(), deviceDO);
            this.saveBatch(list);
        }
    }

    @Override
    public void importExcel(MultipartFile file, String companyId) {
        ImportParams params = new ImportParams();

        List<DeviceRepairImportExcel> importExcelList = new ArrayList<>();
        try {
            importExcelList = ExcelImportUtil.importExcel(file.getInputStream(), DeviceRepairImportExcel.class, params);
        } catch (Exception exception) {
            exception.printStackTrace();
        }

        if (ObjectUtils.isEmpty(importExcelList)) {
            throw new ApiException(ResultCode.FAILED);
        }

        int count = 0;
        for (DeviceRepairImportExcel excel : importExcelList) {
            count++;
            DeviceDO deviceDO = deviceMapper.selectOne(Wrappers.<DeviceDO>lambdaQuery()
                    .eq(DeviceDO::getCompanyId, companyId)
                    .eq(DeviceDO::getDeviceNo, excel.getDeviceNo())
            );
            if (ObjectUtils.isEmpty(deviceDO)) {
                throw new ApiException(ResultCode.FAILED);
            }

            DeviceRepairDO deviceRepairDO = new DeviceRepairDO();
            BeanUtils.copyProperties(deviceMapper, deviceRepairDO);

            //固定参数
            deviceRepairDO.setCompanyId(companyId);
            deviceRepairDO.setDeviceId(deviceDO.getId());

            //加工点检内容
            List<Map<String, Object>> mapList = new ArrayList<>();
            Map<String, Object> map1 = new HashMap<>();
            map1.put("title", "紧急维修");
            if (count % 2 == 0) {
                map1.put("checked", "false");
            } else {
                map1.put("checked", "true");
            }
            mapList.add(map1);

            if (excel.getRepairStatus().equals("已完成")) {
                deviceRepairDO.setRepairStatus(1);
            } else {
                deviceRepairDO.setRepairStatus(0);
            }

            deviceRepairDO.setCreateTime(excel.getStartTime());
            deviceRepairDO.setRepairContent(JSONObject.toJSONString(mapList));
            deviceRepairDO.setUpdateTime(deviceRepairDO.getCreateTime());

            deviceRepairMapper.insert(deviceRepairDO);
        }
    }

    public List<DeviceRepairDO> generateRepairData(String startDateStr, String endDateStr, int repairCount, DeviceDO deviceDO) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");

        Date startDate = null;
        Date endDate = null;
        try {
            startDate = dateFormat.parse(startDateStr + " 08:00");
            endDate = dateFormat.parse(endDateStr + " 18:00");
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }

        //计算相差天数平均值：周期天数/次数
        // 将 Date 转换为 LocalDate
        LocalDate startLocalDate = startDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        LocalDate endLocalDate = endDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        int averageDay = (int) ChronoUnit.DAYS.between(startLocalDate, endLocalDate) / repairCount;

        //查询模版，如果模版为空则报错
        DeviceTemplateDO deviceTemplateDO = deviceTemplateMapper.selectOne(Wrappers.<DeviceTemplateDO>lambdaQuery()
                .eq(DeviceTemplateDO::getCompanyId, deviceDO.getCompanyId())
                .eq(DeviceTemplateDO::getType, 1)
                .last(" limit 1")
        );
        if (ObjectUtils.isEmpty(deviceTemplateDO)) {
            throw new ApiException(ResultCode.FAILED, "未查询到设备绑定的维修模版");
        }

        List<DeviceRepairDO> deviceRepairDOList = new ArrayList<>();

        Calendar cal = Calendar.getInstance();
        cal.setTime(startDate);

        Random random = new Random();
        for (int i = 0; i < repairCount; i++) {
            DeviceRepairDO deviceRepairDO = new DeviceRepairDO();

            deviceRepairDO.setCompanyId(deviceDO.getCompanyId());
            deviceRepairDO.setDeviceId(deviceDO.getId());
            deviceRepairDO.setRepairNo(UUID.randomUUID().toString());

            //获取模版内容
            List<TemplateResponse.TemplateContent> templateContentList = JSONArray.parseArray(deviceTemplateDO.getTemplateContent(), TemplateResponse.TemplateContent.class);
            //存入结果
            List<TemplateResponse.TemplateResult> templateResultList = new ArrayList<>();
            for (TemplateResponse.TemplateContent templateContent : templateContentList) {
                TemplateResponse.TemplateResult templateResult = new TemplateResponse.TemplateResult();
                BeanUtils.copyProperties(templateContent, templateResult);
                templateResult.setChecked("true");
                templateResultList.add(templateResult);
            }
            //转换字符串存入对象
            deviceRepairDO.setRepairContent(JSONObject.toJSONString(templateResultList));

            deviceRepairDO.setRepairChannel(0);
            deviceRepairDO.setRepairStatus(1);

            int randomNumber = new Random().nextInt(5) + 1;

            Date repairStartTime = DateTimeUtils.getRandomTime(cal.getTime(), 8, 18);
            Date repairEndTime = DateTimeUtils.getRandomEndTime(repairStartTime, 0.5, 2);

            deviceRepairDO.setStartTime(repairStartTime);
            deviceRepairDO.setStartBy("管理员" + randomNumber);
            deviceRepairDO.setEndTime(repairEndTime);
            deviceRepairDO.setEndBy("管理员" + randomNumber);

            deviceRepairDO.setCreateBy("管理员" + randomNumber);
            deviceRepairDO.setCreateTime(repairStartTime);
            deviceRepairDO.setUpdateTime(repairEndTime);
            deviceRepairDO.setDeleted(0);

            deviceRepairDOList.add(deviceRepairDO);

            // 随机生成下一次维修时间
            cal.add(Calendar.DATE, random.nextInt(averageDay) + 1); // 随机隔几天再生成
        }
        return deviceRepairDOList;
    }

}




